<template>
  <ContentWrap>
    <!-- 搜索工作栏 -->
    <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true"
             label-width="68px">
      <el-form-item label="日期" prop="date">
        <el-date-picker v-model="queryParams.date" value-format="YYYY-MM-DD HH:mm:ss"
                        type="daterange" class="!w-240px"
                        start-placeholder="开始日期" end-placeholder="结束日期"
                        :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
                        :picker-options="pickerOptions" @change="handleQuery"/>
      </el-form-item>
      <!--<el-form-item label="账户" prop="orgId">
        <el-select v-model="queryParams.orgId" placeholder="请选择账户" clearable class="!w-140px" @change="handleQuery">
          <el-option v-for="dict in getIntDictOptions(DICT_TYPE.ASA_ORG_ID)" :key="dict.value" :label="dict.label"
            :value="dict.value" />
        </el-select>
      </el-form-item>-->
      <el-form-item label="应用">
        <el-select v-model="queryParams.adamIds" placeholder="请选择应用" clearable class="!w-240px"
                   @change="handleQuery" multiple collapse-tags>
          <el-option v-for="dict in getIntDictOptions(DICT_TYPE.ASA_APP_ID)" :key="dict.value"
                     :label="dict.label" :value="dict.value"/>
        </el-select>
      </el-form-item>
      <el-form-item label="显示列">
        <!-- 列显示控制 -->
        <el-select v-model="vColumns" class="!w-180px" multiple placeholder="选择显示的列"
                   @change="saveColumnsToLocalStorage" collapse-tags>
          <el-option label="账户" value="orgId"/>
          <el-option label="广告支出" value="localSpendAmount"/>
          <el-option label="销售额" value="ascSales"/>
          <el-option label="订阅所得" value="ascProceeds"/>
          <el-option label="利润CNY" value="profit"/>
          <el-option label="总安装" value="ascInstalls"/>
          <el-option label="广告安装" value="installs"/>
          <el-option label="自然新增" value="naturalIncrease"/>
          <el-option label="试订数" value="ascTrial"/>
          <el-option label="试订率" value="trialRate"/>
          <el-option label="订阅数" value="ascRenewal"/>
          <el-option label="退款数" value="ascRefund"/>
          <el-option label="退款销售额" value="ascRefundSales"/>
          <el-option label="退款所得" value="ascRefundProceeds"/>
          <el-option label="广告展示" value="impressions"/>
          <el-option label="广告点击" value="taps"/>
          <el-option label="广告新安装" value="newDownloads"/>
          <el-option label="广告重复安装" value="reDownloads"/>
          <el-option label="广告点击率" value="ttr"/>
          <el-option label="广告转化率" value="conversionRate"/>
          <el-option label="广告转化费用" value="avgCpaAmount"/>
          <el-option label="广告点击付费" value="avgCptAmount"/>
          <el-option label="广告千展费用" value="avgCpmAmount"/>
          <el-option label="广告支出货币" value="localSpendCurrency"/>
          <el-option label="展示次数" value="ascImpressions"/>
          <el-option label="点击次数" value="ascTaps"/>
          <el-option label="点击率" value="ascTtr"/>
          <el-option label="转化率" value="ascConversionRate"/>
          <el-option label="创建时间" value="createTime"/>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button @click="handleQuery">
          <Icon icon="ep:search" class="mr-5px"/>
          搜索
        </el-button>
        <el-button @click="resetQuery">
          <Icon icon="ep:refresh" class="mr-5px"/>
          重置
        </el-button>
        <el-button type="success" plain @click="handleExport" :loading="exportLoading"
                   v-hasPermi="['asasc:campaign-grand-totals:export']">
          <Icon icon="ep:download" class="mr-5px"/>
          导出
        </el-button>
      </el-form-item>
    </el-form>
  </ContentWrap>

  <!-- 列表 -->
  <ContentWrap>
    <el-table class="responsive-table" v-loading="loading" :data="list" :stripe="true"
              :show-overflow-tooltip="true"
              show-summary :summary-method="getSummaries">
      <el-table-column v-if="vColumns.includes('orgId')" label="账户" align="center" prop="orgId"
                       :min-width="100" sortable>
        <template #default="scope">
          <dict-tag :type="DICT_TYPE.ASA_ORG_ID" :value="scope.row.orgId"/>
        </template>
      </el-table-column>
      <el-table-column label="应用" align="center" prop="adamId" :min-width="120" sortable>
        <template #default="scope">
          <dict-tag :type="DICT_TYPE.ASA_APP_ID" :value="scope.row.adamId"/>
        </template>
      </el-table-column>
      <el-table-column label="日期" align="center" prop="date" :min-width="100" sortable fixed/>
      <el-table-column v-if="vColumns.includes('localSpendAmount')" label="广告支出" align="center"
                       :formatter="(row) => fenToYuanFormat(row.localSpendCurrency, row.localSpendAmount, 0)"
                       prop="localSpendAmount" :min-width="100" sortable/>
      <el-table-column v-if="vColumns.includes('ascSales')" label="销售额" align="center"
                       :formatter="(row) => fenToYuanFormat(row.localSpendCurrency, row.ascSales,0)"
                       prop="ascSales" :min-width="100"
                       sortable/>
      <el-table-column v-if="vColumns.includes('ascProceeds')" label="订阅所得" align="center"
                       prop="ascProceeds" :min-width="100" sortable
                       :formatter="(row) => fenToYuanFormat(row.localSpendCurrency, row.ascProceeds,0)"/>
      <el-table-column label="利润" align="center" prop="profit" :min-width="100" sortable>
        <template #default="scope">
          <span
            :style="{ color: (scope.row.ascProceeds - scope.row.localSpendAmount
            + scope.row.ascRefundProceeds) > 0 ? 'red' : 'green' }">
            {{
              fenToYuanFormat(scope.row.localSpendCurrency, (scope.row.ascProceeds
                - scope.row.localSpendAmount + scope.row.ascRefundProceeds), 0)
            }}
          </span>
        </template>
      </el-table-column>
      <el-table-column v-if="vColumns.includes('ascRefundProceeds')" label="退款所得" align="center"
                       prop="ascRefundProceeds" :min-width="100" sortable
                       :formatter="(row) => fenToYuanFormat(row.localSpendCurrency, row.ascRefundProceeds,0)"/>
      <el-table-column v-if="vColumns.includes('ascInstalls')" label="总安装" align="center"
                       prop="ascInstalls" :min-width="90" sortable/>
      <el-table-column v-if="vColumns.includes('installs')" label="广告安装" align="center"
                       prop="installs" sortable :min-width="90"/>
      <el-table-column v-if="vColumns.includes('naturalIncrease')" label="自然新增" align="center"
                       prop="naturalIncrease" :min-width="90" sortable>
        <template #default="scope">
          {{ scope.row.ascInstalls - scope.row.installs }}
        </template>
      </el-table-column>
      <el-table-column v-if="vColumns.includes('ascTrial')" label="试订数" align="center"
                       prop="ascTrial" :min-width="85" sortable/>
      <el-table-column v-if="vColumns.includes('trialRate')" label="试订率" align="center"
                       prop="trialRate" :formatter="toPercentage" :min-width="85" sortable/>
      <el-table-column v-if="vColumns.includes('ascRenewal')" label="订阅数" align="center"
                       prop="ascRenewal" :min-width="85" sortable/>
      <el-table-column v-if="vColumns.includes('ascRefund')" label="退款数" align="center"
                       prop="ascRefund" :min-width="85" sortable/>
      <el-table-column v-if="vColumns.includes('ascRefundSales')" label="退款销售额" align="center"
                       prop="ascRefundSales" :min-width="100" sortable
                       :formatter="(row) => fenToYuanFormat(row.localSpendCurrency, row.ascRefundSales,0)"/>
      <el-table-column v-if="vColumns.includes('impressions')" label="广告展示" align="center"
                       prop="impressions" sortable/>
      <el-table-column v-if="vColumns.includes('taps')" label="广告点击" align="center" prop="taps"
                       sortable/>
      <el-table-column v-if="vColumns.includes('newDownloads')" label="广告新安装" align="center"
                       prop="newDownloads" sortable/>
      <el-table-column v-if="vColumns.includes('reDownloads')" label="广告重复安装" align="center"
                       prop="reDownloads" sortable/>
      <el-table-column v-if="vColumns.includes('ttr')" label="广告点击率" :formatter="toPercentage"
                       align="center" prop="ttr" sortable/>
      <el-table-column v-if="vColumns.includes('conversionRate')" label="广告转化率"
                       :formatter="toPercentage" align="center"
                       prop="conversionRate" sortable/>
      <el-table-column v-if="vColumns.includes('avgCpaAmount')" label="广告转化费用" align="center"
                       :formatter="(row) => fenToYuanFormat(row.avgCpaCurrency, row.avgCpaAmount)"
                       prop="avgCpaAmount" :min-width="100" sortable/>
      <el-table-column v-if="vColumns.includes('avgCptAmount')" label="广告点击付费" align="center"
                       :formatter="(row) => fenToYuanFormat(row.avgCptCurrency, row.avgCptAmount)"
                       prop="avgCptAmount" :min-width="100" sortable/>
      <el-table-column v-if="vColumns.includes('avgCpmAmount')" label="广告千展费用" align="center"
                       :formatter="(row) => fenToYuanFormat(row.avgCpmCurrency, row.avgCpmAmount)"
                       prop="avgCpmAmount" :min-width="100" sortable/>
      <el-table-column v-if="vColumns.includes('localSpendCurrency')" label="广告支出货币"
                       align="center" prop="localSpendCurrency" sortable/>
      <el-table-column v-if="vColumns.includes('ascImpressions')" label="展示次数" align="center"
                       prop="ascImpressions" :min-width="100" sortable/>
      <el-table-column v-if="vColumns.includes('ascTaps')" label="点击次数" align="center"
                       prop="ascTaps" :min-width="100" sortable/>
      <el-table-column v-if="vColumns.includes('ascTtr')" label="点击率" align="center"
                       prop="ascTtr" :formatter="toPercentage" :min-width="85" sortable/>
      <el-table-column v-if="vColumns.includes('ascConversionRate')" label="转化率" align="center"
                       prop="ascConversionRate" :formatter="toPercentage" :min-width="100"
                       sortable/>
      <el-table-column v-if="vColumns.includes('createTime')" label="创建时间" width="140px"
                       align="center" :formatter="dateFormatter" prop="createTime" sortable/>
    </el-table>
    <!-- 分页 -->
    <Pagination :total="total" v-model:page="queryParams.pageNo"
                v-model:limit="queryParams.pageSize"
                @pagination="getList"/>
  </ContentWrap>

  <!-- 表单弹窗：添加/修改 -->
  <CampaignGrandTotalsForm ref=" formRef" @success="getList"/>
</template>

<style scoped>
.responsive-table {
  height: 650px;
}

@media (max-width: 768px) and (orientation: portrait) {
  .responsive-table {
    height: 400px;
    /* 移动设备竖屏高度 */
  }
}

@media (max-width: 768px) and (orientation: landscape) {
  .responsive-table {
    height: 300px;
    /* 移动设备横屏高度 */
  }
}
</style>

<script setup lang="ts">
import {DICT_TYPE, getIntDictOptions} from '@/utils/dict'
import download from '@/utils/download'
import {CampaignGrandTotalsApi, CampaignGrandTotalsVO} from '@/api/asasc/campaignTotals'
import CampaignGrandTotalsForm from './CampaignGrandTotalsForm.vue'
import {fenToYuanFormat, toPercentage} from "@/utils";
import {onMounted, reactive, ref} from 'vue';
import {dateFormatter} from "@/utils/formatTime";
import {useI18n} from 'vue-i18n';

// 获取当前日期和过去7天的日期，并格式化为 'yyyy-MM-dd HH:mm:ss'，使用北京时间
const getDefaultDateRange = () => {
  const toBeijingTime = (date) => {
    const offset = date.getTimezoneOffset() * 60000;
    // 28800000ms = 8 hours
    return new Date(date.getTime() + offset + 28800000);
  };

  const formatDateTime = (date) => {
    const y = date.getFullYear();
    const m = String(date.getMonth() + 1).padStart(2, '0');
    const d = String(date.getDate()).padStart(2, '0');
    const h = String(date.getHours()).padStart(2, '0');
    const min = String(date.getMinutes()).padStart(2, '0');
    const s = String(date.getSeconds()).padStart(2, '0');
    return `${y}-${m}-${d} ${h}:${min}:${s}`;
  };

  const endDate = toBeijingTime(new Date());
  const startDate = toBeijingTime(new Date());
  startDate.setDate(startDate.getDate() - 2); // 这里修正为 startDate
  endDate.setDate(endDate.getDate() - 2); // 这里修正为 startDate

  // 设置开始时间为 00:00:00，结束时间为 23:59:59
  startDate.setHours(0, 0, 0, 0);
  endDate.setHours(23, 59, 59, 999);

  // console.log(formatDateTime(startDate), formatDateTime(endDate));
  return [formatDateTime(startDate), formatDateTime(endDate)];
};

// 快捷选项
const pickerOptions = {
  shortcuts: [
    {
      text: '昨天',
      onClick(picker) {
        const end = new Date();
        end.setDate(end.getDate() - 1);
        const start = new Date(end);
        start.setHours(0, 0, 0, 0);
        end.setHours(23, 59, 59, 999);
        picker.$emit('pick', [start, end]);
      },
    },
    {
      text: '过去 7 天',
      onClick(picker) {
        const end = new Date();
        const start = new Date();
        start.setDate(end.getDate() - 7);
        start.setHours(0, 0, 0, 0);
        end.setHours(23, 59, 59, 999);
        picker.$emit('pick', [start, end]);
      },
    },
    {
      text: '过去 30 天',
      onClick(picker) {
        const end = new Date();
        const start = new Date();
        start.setDate(end.getDate() - 30);
        start.setHours(0, 0, 0, 0);
        end.setHours(23, 59, 59, 999);
        picker.$emit('pick', [start, end]);
      },
    },
    {
      text: '过去 90 天',
      onClick(picker) {
        const end = new Date();
        const start = new Date();
        start.setDate(end.getDate() - 90);
        start.setHours(0, 0, 0, 0);
        end.setHours(23, 59, 59, 999);
        picker.$emit('pick', [start, end]);
      },
    },
    {
      text: '本月',
      onClick(picker) {
        const end = new Date();
        const start = new Date(end.getFullYear(), end.getMonth(), 1);
        start.setHours(0, 0, 0, 0);
        end.setHours(23, 59, 59, 999);
        picker.$emit('pick', [start, end]);
      },
    },
    {
      text: '上个月',
      onClick(picker) {
        const end = new Date();
        end.setDate(0); // 上个月的最后一天
        const start = new Date(end.getFullYear(), end.getMonth(), 1);
        start.setHours(0, 0, 0, 0);
        end.setHours(23, 59, 59, 999);
        picker.$emit('pick', [start, end]);
      },
    },
  ],
};

/** 广告数据汇总 列表 */
defineOptions({name: 'CampaignGrandTotals'})

const message = useMessage() // 消息弹窗
const {t} = useI18n() // 国际化

const loading = ref(true) // 列表的加载中
const list = ref<CampaignGrandTotalsVO[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
  pageNo: 1,
  pageSize: 100,
  orgId: undefined,
  adamIds: undefined,
  date: getDefaultDateRange() // 默认选择过去7天
});
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
const vColumns = ref(["impressions", "taps", "installs", "conversionRate", "avgCpaAmount",
  "avgCpmAmount", "avgCptAmount", "localSpendAmount", "ttr", "ascProceeds", "ascInstalls", "ascTrial",
  "ascRenewal", "naturalIncrease"])
// 默认显示的列

/** 查询列表 */
const getList = async () => {
  loading.value = true
  try {
    const data = await CampaignGrandTotalsApi.getCampaignGrandTotalsPage(queryParams)
    list.value = data.list
    total.value = data.total
  } finally {
    loading.value = false
  }
}

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value.resetFields()
  handleQuery()
}

/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
  formRef.value.open(type, id)
}

/** 导出按钮操作 */
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const data = await CampaignGrandTotalsApi.exportCampaignGrandTotals(queryParams)
    download.excel(data, '广告数据日报表.xls')
  } catch {
  } finally {
    exportLoading.value = false
  }
}

// 保存列设置到 localStorage
const saveColumnsToLocalStorage = () => {
  localStorage.setItem('campaignTotal.vColumns', JSON.stringify(vColumns.value));
};

/** 初始化 **/
onMounted(() => {
  const savedColumns = localStorage.getItem('campaignTotal.vColumns');
  if (savedColumns) {
    vColumns.value = JSON.parse(savedColumns);
  }

  getList()
})

/** 汇总方法 */
const getSummaries = (param) => {
  const {columns, data} = param;
  const sums = [];
  let totalImpressions = 0;
  let totalTaps = 0;
  let totalInstalls = 0;
  let totalSpend = 0;
  let currency = '';
  let ascTrial = 0;
  let ascInstalls = 0;

  columns.forEach((column, index) => {
    if (index === 0) {
      sums[index] = '总计';
      return;
    }
    const values = data.map(item => Number(item[column.property]));
    if (!values.every(value => isNaN(value))) {
      const sum = values.reduce((prev, curr) => {
        const value = Number(curr);
        if (!isNaN(value)) {
          return prev + curr;
        } else {
          return prev;
        }
      }, 0);

      if (column.property === 'createTime'
        || column.property === 'adamId'
        || column.property === 'dailyBudgetAmount') {
        sums[index] = '';
      } else if (column.property === 'impressions') {
        totalImpressions = sum;
        sums[index] = sum;
      } else if (column.property === 'taps') {
        totalTaps = sum;
        sums[index] = sum;
      } else if (column.property === 'installs') {
        totalInstalls = sum;
        sums[index] = sum;
      } else if (column.property === 'ascInstalls') {
        ascInstalls = sum;
        sums[index] = sum;
      } else if (column.property === 'ascTrial') {
        ascTrial = sum;
        sums[index] = sum;
      } else if (column.property === 'localSpendAmount') {
        totalSpend = sum;
        currency = data[0]?.localSpendCurrency.replace('RMB', '¥').replace('USD', '$') || ''; // 使用第一个数据项的货币符号
        sums[index] = `${currency}${sum.toFixed(0)}`;
      } else if (column.property === 'ttr') {
        const ttr = totalImpressions ? (totalTaps / totalImpressions) * 100 : 0;
        sums[index] = `${ttr.toFixed(0)}%`;
      } else if (column.property === 'conversionRate') {
        const conversionRate = totalTaps ? (totalInstalls / totalTaps) * 100 : 0;
        sums[index] = `${conversionRate.toFixed(0)}%`;
      } else if (column.property === 'avgCpaAmount') {
        const avgCpaAmount = totalInstalls ? totalSpend / totalInstalls : 0;
        sums[index] = `${currency}${avgCpaAmount.toFixed(2)}`;
      } else if (column.property === 'avgCptAmount') {
        const avgCptAmount = totalTaps ? totalSpend / totalTaps : 0;
        sums[index] = `${currency}${avgCptAmount.toFixed(2)}`;
      } else if (column.property === 'trialRate') {
        const trialRate = ascTrial ? (ascTrial / ascInstalls) * 100 : 0;
        sums[index] = `${trialRate.toFixed(0)}%`;
      } else if (column.property === 'avgCpmAmount') {
        const avgCpmAmount = totalImpressions ? (totalSpend / totalImpressions) * 1000 : 0;
        sums[index] = `${currency}${avgCpmAmount.toFixed(2)}`;
      } else if (column.property === 'ascSales' || column.property === 'ascProceeds'
        || column.property === 'ascRefundSales' || column.property === 'ascRefundProceeds') {
        sums[index] = `${currency}${sum.toFixed(0)}`;
      } else {
        sums[index] = sum;
      }
    } else {
      sums[index] = '';
    }
  });

  // 计算利润总和
  const totalProfit = data.reduce((prev, curr) => prev + (curr.ascProceeds
    - curr.localSpendAmount + curr.ascRefundProceeds), 0);
  const profitIndex = columns.findIndex(column => column.label === '利润');
  if (profitIndex !== -1) {
    sums[profitIndex] = `¥${totalProfit.toFixed(0)}`;
  }

  // 计算自然新增总和
  const naturalIncreaseIndex = columns.findIndex(column => column.label === '自然新增');
  const asaInstallsIndex = columns.findIndex(column => column.label === '总安装');
  const adInstallsIndex = columns.findIndex(column => column.label === '广告安装');
  if (naturalIncreaseIndex !== -1) {
    sums[naturalIncreaseIndex] = sums[asaInstallsIndex] - sums[adInstallsIndex];
  }

  return sums;
};
</script>
